<?php
namespace libs\qoy\Cache;
use libs\qoy\Exception\ExceptionInternalServerError;
/**
 * Memecahce MC缓存
 *
 * - 使用序列化对需要存储的值进行转换，以提高速度
 * - 默认不使用zlib对值压缩
 * - 请尽量使用Memcached扩展
 * @param array $config 初始化配置
 * @param string $config['host'] Memcache域名
 * @param int $config['port'] Memcache端口
 * @param string $config['prefix'] key 前缀
 * @throws ExceptionInternalServerError
 */

class Memcache implements ICache {

    protected $memcache = null;

    protected $prefix;
    
    protected $config  = [
        'host'         => '127.0.0.1', // memcache主机
        'port'         => 11211, // memcache端口
        'prefix' => '', // memcache key前缀
    ];
   
    /**
     * 构造方法
     * @param array $config 初始化配置
     * @param string $config['host'] Memcache域名
     * @param int $config['port'] Memcache端口
     * @param string $config['prefix'] key 前缀
     * @throws ExceptionInternalServerError
    */
    
    
    public function __construct(array $config=[]) {
        
        if (!extension_loaded('memcached')) {
            throw new ExceptionInternalServerError(ExceptionInternalServerError::SUPPORT_MEMCACHE);
        }
        
        $this->config = array_merge($this->config, $config);
        
        
        $this->memcache = $this->createMemcache();
         // 支持集群
        $hosts = explode(',', $this->config['host']);
        $ports = explode(',', $this->config['port']);
        if (empty($ports[0])) {
            $ports[0] = 11211;
        }
        // 建立连接
        $servers = [];
        foreach ((array) $hosts as $i => $host) {
            $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1];
        }
        $this->memcache->addServer($servers);
        
        $this->prefix = isset($this->config['prefix']) ? $this->config['prefix'] : '';
       
        
        
    }
    /**
     * @see ICache->set
     */
    public function set(string $key, $value,int $expire = 600) {
        $this->memcache->set($this->formatKey($key), @serialize($value), 0, $expire);
    }
    /**
     * @see ICache->get
     */
    public function get(string $key) {
        $value = $this->memcache->get($this->formatKey($key));
        return $value !== FALSE ? @unserialize($value) : NULL;
    }
    /**
     * @see ICache->delete
     */
    public function delete(string $key) {
        return $this->memcache->delete($this->formatKey($key));
    }
    
    /**
     * 获取MC实例，以便提供桩入口
     * @return Memcache
     */
    protected function createMemcache() {
        return new Memcache();
    }
    
    protected function formatKey(string $key) {
        return $this->prefix . $key;
    }
}
